Skip to content

Conversation

@YixingZhang007
Copy link
Contributor

@YixingZhang007 YixingZhang007 commented Oct 23, 2025

This PR is still working in progress. Thank you for your understanding!

@YixingZhang007 YixingZhang007 marked this pull request as draft October 23, 2025 14:44
@llvmbot
Copy link
Member

llvmbot commented Oct 23, 2025

@llvm/pr-subscribers-backend-spir-v

Author: None (YixingZhang007)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/164829.diff

1 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp (+30)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 9f2e07508a36a..64e076338816f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -3013,6 +3013,36 @@ bool SPIRVEmitIntrinsics::runOnModule(Module &M) {
   parseFunDeclarations(M);
   insertConstantsForFPFastMathDefault(M);
 
+  // If there are no functions but there is at least one global variable,
+  // create a shadow function to "anchor" global handling in codegen.
+  bool HasAnyFunction = false;
+  for (auto &F : M)
+    if (!F.isDeclaration() && !F.isIntrinsic())
+      HasAnyFunction = true;
+
+  Function *ShadowFunc = nullptr;
+  if (!HasAnyFunction) {
+      for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ) {
+          GlobalVariable *GV = &*GI++;
+          if (GV->hasInternalLinkage()) {
+              GV->eraseFromParent();
+              Changed = true;
+          } else if (ShadowFunc == nullptr) {
+              LLVMContext &Ctx = M.getContext();
+              auto *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false);
+              ShadowFunc = Function::Create(
+                  FTy, GlobalValue::InternalLinkage, "__spirv_globals_entry", &M);
+
+              // Create a basic block and insert a ret void
+              BasicBlock *BB = BasicBlock::Create(Ctx, "entry", ShadowFunc);
+              IRBuilder<> B(BB);
+              B.CreateRetVoid();
+
+              Changed = true;
+          }
+      }
+  }
+
   TodoType.clear();
   for (auto &F : M)
     Changed |= runOnFunction(F);

@github-actions
Copy link

github-actions bot commented Oct 23, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff origin/main HEAD --extensions cpp -- llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp --diff_from_common_commit

⚠️
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing origin/main to the base branch/commit you want to compare against.
⚠️

View the diff from clang-format here.
diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index cc6d122c0..ae48f4dd8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -304,9 +304,10 @@ void SPIRVAsmPrinter::emitInstruction(const MachineInstr *MI) {
 void SPIRVAsmPrinter::outputModuleSection(SPIRV::ModuleSectionType MSType) {
   const Function &F = MF->getFunction();
   for (const MachineInstr *MI : MAI->getMSInstrs(MSType)) {
-    if (F.getName() != "__spirv_globals_entry" || ((MI->getOpcode() != SPIRV::OpName) 
-                                    && (MI->getOpcode() != SPIRV::OpTypeVoid)
-                                    && (MI->getOpcode() != SPIRV::OpTypeFunction))) { 
+    if (F.getName() != "__spirv_globals_entry" ||
+        ((MI->getOpcode() != SPIRV::OpName) &&
+         (MI->getOpcode() != SPIRV::OpTypeVoid) &&
+         (MI->getOpcode() != SPIRV::OpTypeFunction))) {
       outputInstruction(MI);
     }
   }
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 7a67cb35d..3b8bfd2eb 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -3029,25 +3029,25 @@ bool SPIRVEmitIntrinsics::runOnModule(Module &M) {
 
   Function *ShadowFunc = nullptr;
   if (!HasAnyFunction) {
-      for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ) {
-          GlobalVariable *GV = &*GI++;
-          if (GV->hasInternalLinkage()) {
-              GV->eraseFromParent();
-              Changed = true;
-          } else if (ShadowFunc == nullptr) {
-              LLVMContext &Ctx = M.getContext();
-              auto *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false);
-              ShadowFunc = Function::Create(
-                  FTy, GlobalValue::InternalLinkage, "__spirv_globals_entry", &M);
-
-              // Create a basic block and insert a ret void
-              BasicBlock *BB = BasicBlock::Create(Ctx, "entry", ShadowFunc);
-              IRBuilder<> B(BB);
-              B.CreateRetVoid();
-
-              Changed = true;
-          }
+    for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE;) {
+      GlobalVariable *GV = &*GI++;
+      if (GV->hasInternalLinkage()) {
+        GV->eraseFromParent();
+        Changed = true;
+      } else if (ShadowFunc == nullptr) {
+        LLVMContext &Ctx = M.getContext();
+        auto *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false);
+        ShadowFunc = Function::Create(FTy, GlobalValue::InternalLinkage,
+                                      "__spirv_globals_entry", &M);
+
+        // Create a basic block and insert a ret void
+        BasicBlock *BB = BasicBlock::Create(Ctx, "entry", ShadowFunc);
+        IRBuilder<> B(BB);
+        B.CreateRetVoid();
+
+        Changed = true;
       }
+    }
   }
 
   TodoType.clear();

@YixingZhang007 YixingZhang007 force-pushed the solve_external_global_variable_issue branch from ea674a6 to 63ae5de Compare November 12, 2025 17:39
@YixingZhang007 YixingZhang007 force-pushed the solve_external_global_variable_issue branch from 63ae5de to 388e124 Compare November 12, 2025 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants